package com.ruoyi.web.controller.system;

import cn.dev33.satoken.annotation.SaIgnore;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.*;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SaTokenUtils;
import com.ruoyi.framework.web.service.WechatLoginService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

/**
 * 微信登录控制器
 *
 * @author ruoyi
 */
@Slf4j
@RestController
@RequestMapping("/wechat")
@Tag(name = "微信登录")
@RequiredArgsConstructor
public class WechatLoginController {

    private final WechatLoginService wechatLoginService;

    /**
     * 微信小程序登录
     *
     * @param loginBody 登录信息
     * @return 登录结果
     */
    @SaIgnore
    @Operation(summary = "微信小程序登录")
    @PostMapping("/mini-login")
    public AjaxResult wechatMiniLogin(@RequestBody WechatLoginBody loginBody) {
        try {
            Object result = wechatLoginService.wechatMiniLogin(loginBody.getCode());

            if (result instanceof String) {
                // 返回的是token，登录成功
                return AjaxResult.success("微信登录成功").put(Constants.TOKEN, result);
            } else if (result instanceof WechatUserInfo) {
                // 返回的是用户信息，需要绑定账号
                return AjaxResult.success("微信登录成功，需要绑定账号")
                        .put("needBind", true)
                        .put("wechatUser", result);
            } else {
                log.error("微信登录返回了未知类型: {}", result != null ? result.getClass().getName() : "null");
                return AjaxResult.error("微信登录异常");
            }
        } catch (Exception e) {
            log.error("微信小程序登录失败", e);
            return AjaxResult.error("微信登录失败，请稍后重试");
        }
    }

    /**
     * 绑定微信账号
     *
     * @param bindBody 绑定信息
     * @return 绑定结果
     */
    @SaIgnore
    @Operation(summary = "绑定微信账号")
    @PostMapping("/bind")
    public AjaxResult bindAccount(@RequestBody WechatBindBody bindBody) {
        try {
            String token = wechatLoginService.bindWechatAccount(bindBody.getOpenid(), bindBody.getPhoneNumber());
            return AjaxResult.success("绑定成功").put(Constants.TOKEN, token);
        } catch (ServiceException e) {
            if ("该手机号已绑定其他微信账号，请先解绑".equals(e.getMessage())) {
                return AjaxResult.error("该手机号已绑定其他微信账号").put("needUnbind", true).put("msg", "NEED_UNBIND");
            }
            return AjaxResult.error(e.getMessage());
        } catch (Exception e) {
            log.error("绑定微信账号失败", e);
            return AjaxResult.error("绑定失败，请稍后重试");
        }
    }

    /**
     * 强制解绑并重新绑定
     *
     * @param rebindBody 重新绑定信息
     * @return 绑定结果
     */
    @SaIgnore
    @Operation(summary = "强制解绑并重新绑定")
    @PostMapping("/force-rebind")
    public AjaxResult forceRebind(@RequestBody WechatForceRebindBody rebindBody) {
        try {
            if (!rebindBody.isConfirmUnbind()) {
                return AjaxResult.error("请确认解绑操作");
            }

            String token = wechatLoginService.forceRebindWechat(rebindBody.getOpenid(), rebindBody.getPhoneNumber());
            return AjaxResult.success("重新绑定成功").put(Constants.TOKEN, token);
        } catch (Exception e) {
            log.error("强制重新绑定失败", e);
            return AjaxResult.error("重新绑定失败，请稍后重试");
        }
    }

    /**
     * 解绑微信账号
     *
     * @return 解绑结果
     */
    @Operation(summary = "解绑微信账号")
    @PostMapping("/unbind")
    public AjaxResult unbindAccount() {
        try {
            LoginUser loginUser = SaTokenUtils.getLoginUser();
            wechatLoginService.unbindWechatAccount(loginUser.getUserId());
            return AjaxResult.success("解绑成功");
        } catch (Exception e) {
            log.error("解绑微信账号失败", e);
            return AjaxResult.error("解绑失败，请稍后重试");
        }
    }

    /**
     * 获取微信绑定状态
     *
     * @return 绑定状态
     */
    @Operation(summary = "获取微信绑定状态")
    @GetMapping("/bind-status")
    public AjaxResult getBindStatus() {
        try {
            LoginUser loginUser = SaTokenUtils.getLoginUser();
            boolean isBound = wechatLoginService.isWechatBound(loginUser.getUserId());
            return AjaxResult.success().put("isBound", isBound);
        } catch (Exception e) {
            log.error("获取微信绑定状态失败", e);
            return AjaxResult.error("获取绑定状态失败");
        }
    }
}
